package com.icinfo.cloud.provider.common.utils;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.icinfo.framework.core.exception.BusinessException;
import com.icinfo.framework.tools.utils.Md5Utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;

@Slf4j
@Component
public class FileEncryptionUtils {

    private static String Algorithm = "AES";
    private static String AlgorithmProvider = "AES/ECB/PKCS5Padding"; // 算法/模式/补码方式
    private static String key="XZCFKEY20230913";
    private static String ossFolder;

    @Value("${oss.folder}")
    private void setOssFolder(String ossFolder) {
        this.ossFolder = ossFolder;
    }

    private static String endpoint;
    @Value("${oss.endpoint}")
    private void setEndpoint(String endpoint) { this.endpoint = endpoint; }

    private static String ossUrlStart;
    @Value("${oss.urlStart}")
    private void setOssUrlStart(String ossUrlStart) {
        this.ossUrlStart = ossUrlStart;
    }

    /**
     * 阅读服务地址
     */
    private static String previewTransferUrl;
    @Value("${previewTransfer.url}")
    private void setPreviewTransferUrl(String previewTransferUrl) {
        this.previewTransferUrl = previewTransferUrl;
    }

    /**
     * 阅读服务预览接口
     */
    private static String visitApi;
    @Value("${previewTransfer.api.visit}")
    private void setVisitApi(String visitApi) {
        this.visitApi = visitApi;
    }

    private static String urlPrefix;
    @Value("${oss.urlPrefix}")
    private  void setUrlPrefix(String urlPrefix) { this.urlPrefix = urlPrefix;}



    /**
     * 字符串加密
     * @author liyafeng
     * @date 2023/9/13
      * @param dataStr
     * @return {@link String}
     */
    public static String encryptionStr(String dataStr) {
        String encryptDataStr ="";
        try {
            String keyMd5=Md5Utils.md5(key);
            encryptDataStr = parseByte2HexStr(encrypt(dataStr, keyMd5.getBytes()));
        }catch (Exception e){
            e.printStackTrace();
            throw new BusinessException("文件信息加密失败");
        }

        return encryptDataStr;
    }


    /**
     *字符串解密
     * @author liyafeng
     * @date 2023/9/13
     * @param enDataStr
     * @return {@link String}
     */
    public static String decryptStr(String enDataStr) {
        String decryptStr="";
        try {
            String keyMd5=Md5Utils.md5(key);
            decryptStr= new String(decrypt(enDataStr, keyMd5.getBytes()), "utf-8");
        }catch (Exception e){
           throw new BusinessException("文书信息解密失败！");
        }
        return  decryptStr;
    }

    /**
     * 加密
     * @param src
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] encrypt(String src, byte[] key) throws Exception {
        SecretKey secretKey = new SecretKeySpec(key, Algorithm);
        Cipher cipher = Cipher.getInstance(AlgorithmProvider);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] cipherBytes = cipher.doFinal(src.getBytes(Charset.forName("utf-8")));
        return cipherBytes;
    }

    /**
     * 解密
     * @param src
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] decrypt(String src, byte[] key) throws Exception {
        SecretKey secretKey = new SecretKeySpec(key, Algorithm);

        // IvParameterSpec ivParameterSpec = getIv();
        Cipher cipher = Cipher.getInstance(AlgorithmProvider);
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] hexBytes = parseHexStr2Byte(src);
        byte[] plainBytes = cipher.doFinal(hexBytes);
        return plainBytes;
    }

    /**
     * 解密成完整的文件地址
     *
     * @param enDataStr
     * @return {@link String }
     * @author shishengyao
     * @date 2023/09/14
     */
    public static String decryptStrToFileUrl(String enDataStr) {
        String decryptStr="";
        try {
            if (enDataStr.startsWith(ossUrlStart)) {
                return enDataStr;
            }
            String keyMd5=Md5Utils.md5(key);
            decryptStr= new String(decrypt(enDataStr, keyMd5.getBytes()), "utf-8");
            decryptStr=urlPrefix+"/"+ossFolder+decryptStr;
        }catch (Exception e){
            throw new BusinessException("文书信息解密失败！");
        }
        return  decryptStr;
    }

    /**
     * 将二进制转换成十六进制
     *
     * @param buf
     * @return
     */
    private static String parseByte2HexStr(byte buf[]) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < buf.length; i++) {
            String hex = Integer.toHexString(buf[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }

    /**
     * 将十六进制转换为二进制
     *
     * @param hexStr
     * @return
     */
    private static byte[] parseHexStr2Byte(String hexStr) {
        if (hexStr.length() < 1) {
            return null;
        } else {
            byte[] result = new byte[hexStr.length() / 2];
            for (int i = 0; i < hexStr.length() / 2; i++) {
                int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
                int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
                result[i] = (byte) (high * 16 + low);
            }
            return result;
        }
    }
    /**
     * 根据文件地址获取加密的后文件名称
     * @author liyafeng
     * @date 2023/9/13
      * @param fileUrl
     * @return {@link String}
     */
    public static String getEncryptFileNameByFileUrl(String fileUrl) {
        String encryptFileNameStr="";
        if(StringUtils.isNotBlank(fileUrl)){
            if (!fileUrl.startsWith(ossUrlStart)) {
                return fileUrl;
            }
            String[] fileUrlArr=fileUrl.split(ossFolder);
            encryptFileNameStr=encryptionStr(fileUrlArr[fileUrlArr.length-1]);
        }
        return encryptFileNameStr;
    }

    /**
     * 获取加密的文件发送地址
     * @author liyafeng
     * @date 2023/9/13
     * @param fileUrl
     * @return {@link String}
     */
    public static String getFileSendEncryptStr(String fileUrl, String phone) {
        String fileSendEncryptStr = "";
        if(StringUtils.isNotBlank(fileUrl)) {
            String[] fileUrlArr = fileUrl.split(ossFolder);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("phone", phone);
            jsonObject.put("fileName", fileUrlArr[fileUrlArr.length-1]);
            String str = jsonObject.toJSONString();
            fileSendEncryptStr = encryptionStr(str);
        }
        return fileSendEncryptStr;
    }

    /**
     * 描述： 根据文件地址获取阅读路径
     *
     * @author: zhengqiang
     * @date: 2023/9/15
     * @param: fileUrl
     * @return {@link String}
     **/
    public static String getFilePreviewUrl(String fileUrl) {
        String filePreviewUrl = "";
        if(StringUtils.isNotBlank(fileUrl)) {
            if (!fileUrl.startsWith(ossUrlStart)) {
                return fileUrl;
            }
            String[] fileUrlArr = fileUrl.split(ossFolder);
            String encryptFileNameStr = encryptionStr(fileUrlArr[fileUrlArr.length-1]);
            filePreviewUrl = previewTransferUrl + visitApi + "?fileUrlEncrypt=" + encryptFileNameStr;
        }
        return filePreviewUrl;
    }

    /**
     * 描述： 根据阅读地址获取oss地址
     *
     * @author: zhengqiang
     * @date: 2023/9/15
     * @param: fileUrl
     * @return {@link String}
     **/
    public static String getOssUrlByFilePreviewUrl(String previewUrl) {
        if(StringUtils.isNotBlank(previewUrl)) {
            //不是阅读地址直接返回原数据
            if (!previewUrl.startsWith(previewTransferUrl + visitApi)) {
                return previewUrl;
            }
            //获取文件地址秘文
            String enDataStr = previewUrl.substring(previewUrl.indexOf("=") + 1);
            return decryptStrToFileUrl(enDataStr);
        }
        return previewUrl;
    }

    /**
     * 是否处罚oss地址或处罚阅读地址
     *
     * @param fileUrl
     * @return
     */
    public static boolean isPunishFileUrl(String fileUrl) {
        if(StringUtils.isBlank(fileUrl)) {
            return false;
        }
        if (fileUrl.startsWith(ossUrlStart)) {
            return true;
        }
        if (fileUrl.startsWith(previewTransferUrl + visitApi)) {
            return true;
        }
        return false;
    }


    public static void main(String[] args) throws Exception {
        System.out.println(getOssUrlByFilePreviewUrl("http://192.168.1.155:8885/api/v2/visit/publish/file/visit?fileUrlEncrypt=3399A7B6662CD535A558F961111422FE2EA4F82475872EB2F1F59FB69BA349029EFB083779A453725C8D42ECC86C81ED"));

        System.out.println(getEncryptFileNameByFileUrl("https://csoss-test.oss-cn-shanghai.aliyuncs.com/xfjdzf/2023/0220/41e0707bda3a49ec9ed8bfcb83cce752.pdf"));

        String name = "2023/0906/9e7b8c92630748a086648f65ff356578.pdf";
        //String name = "pdf";
        String mi = encryptionStr(name);
        System.out.println(mi);
        System.out.println(decryptStr(mi));

        JSONObject jsonObject=new JSONObject();
        jsonObject.put("phone","18868876270");
        jsonObject.put("fileName","2023/0906/9e7b8c92630748a086648f65ff356578.pdf");
        String str=jsonObject.toJSONString();
        String strJm = encryptionStr(str);
        System.out.println(strJm);
        System.out.println(decryptStr(strJm));

    }

}
